<?php

namespace App\Service\OpenShop\Feishu;


use App\Enums\BaseErrorCode;
use App\Enums\OpenShop\InvestmentPromotion\MainProcessEnum;
use App\Enums\OpenShop\MissionTemplateEnum;
use App\Events\OpenShop\OpenShopProcessEvent;
use App\Events\OpenShop\SignSiteMissionEvent;
use App\Http\Resources\OpenShop\ShopCheckAccept\ShopCheckAcceptResource;
use App\Models\Common\ConfigModel;
use App\Models\Cruise\CruiseOrderModel;
use App\Models\Cruise\CruiseOrderProcessModel;
use App\Models\OpenShop\Common\OpenShopOrderManagerModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopMainProcessModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopSignOrderLogModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopSignOrderModel;
use App\Models\OpenShop\ShopCheckAccept\OpenShopCheckAcceptModel;
use App\Models\OpenShop\StartBusiness\OpenShopStartBusinessModel;
use App\Service\BaseService;
use App\Service\Cruise\CruiseTemplate\CruiseTemplateService;
use App\Service\Cruise\Mission\CruiseOrderInputService;
use App\Support\ChangeSupport;
use App\Support\CustomForm\AttributeSupport;
use App\Support\CustomForm\ValidateSupport;
use Exception;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

/**
 * @author Green Leaf <786407418@qq.com>
 */
class ShopCheckAcceptService extends BaseService
{

    /**
     * 指派经理
     *
     * @param object $rmsUser
     * @param object $params
     * @throws Exception
     */
    public static function assignManager(object $rmsUser, object $params)
    {
        try {
            OpenShopCheckAcceptModel::query()
                                    ->where("orderNo", $params->orderNo)
                                    ->update(array_merge([
                                        "assignTime"   => time(),
                                        "updatedAt"    => time(),
                                        "updatedByUid" => $rmsUser->id,
                                        "step"         => MainProcessEnum::SHOP_CHECK_ASSIGN_MANAGER,
                                    ], (array)$params));

            $mainProcessInfo = OpenShopMainProcessModel::query()->where("orderNo", $params->orderNo)->first();
            $mainProcessId   = $mainProcessInfo->id;

            OpenShopOrderManagerModel::generateManagerOrUpdate(
                OpenShopOrderManagerModel::MANAGER_TYPE_5,
                $mainProcessId,
                $params->managerId,
                $params->managerName,
                OpenShopOrderManagerModel::ORDER_STATUS_NORMAL,
                $mainProcessInfo->shopId
            );

            //TODO 任务
            event(new SignSiteMissionEvent(
                $params->orderNo,
                MissionTemplateEnum::STEP_STATUS_11,
                $rmsUser->id
            ));

            //todo 流程日志写入
            event(new OpenShopProcessEvent(
                $rmsUser->id,
                $mainProcessId,
                MainProcessEnum::MAIN_PROCESS_SHOP_CHECK,
                MainProcessEnum::SHOP_CHECK_ASSIGN_MANAGER
            ));


            //todo 主流程更新
            OpenShopMainProcessModel::query()
                                    ->where("orderNo", $params->orderNo)
                                    ->update([
                                        'nowStepStatus' => 12
                                    ]);


        } catch (Exception $exception) {
            handleException($exception);
        }
    }

    /**
     * 只指派经理
     *
     * @param object $rmsUser
     * @param object $params
     * @throws Exception
     */
    public static function onlyAssignManager(object $rmsUser, object $params)
    {
        try {
            $mainProcessInfo = OpenShopMainProcessModel::query()
                                                     ->where("orderNo", $params->orderNo)
                                                     ->orderBy('id', 'desc')
                                                     ->first();
            $mainProcessId = $mainProcessInfo->id;

            OpenShopCheckAcceptModel::query()->updateOrCreate(["orderNo" => $params->orderNo],
                array_merge([
                    'mainProcessId' => $mainProcessId,
                    "assignTime"    => time(),
                    "updatedAt"     => time(),
                    "updatedByUid"  => $rmsUser->id,
                    "step"          => MainProcessEnum::SHOP_CHECK_ASSIGN_MANAGER,
                    'managerId'     => $params->managerId,
                    'managerName'   => $params->managerName,
                ], (array)$params)
            );

            OpenShopOrderManagerModel::generateManagerOrUpdate(
                OpenShopOrderManagerModel::MANAGER_TYPE_5,
                $mainProcessId,
                $params->managerId,
                $params->managerName,
                OpenShopOrderManagerModel::ORDER_STATUS_NORMAL,
                $mainProcessInfo->shopId
            );


            //todo 流程日志写入
            event(new OpenShopProcessEvent(
                $rmsUser->id,
                $mainProcessId,
                MainProcessEnum::MAIN_PROCESS_SHOP_CHECK,
                MainProcessEnum::SHOP_CHECK_ASSIGN_MANAGER
            ));

        } catch (Exception $exception) {
            handleException($exception);
        }
    }

    /**
     * 经理确认 & 表单提交
     *
     * @param object $rmsUser
     * @param object $params
     * @throws Exception
     */
    public static function managerConfirmSubmit(object $rmsUser, object $params, int $formSubmitTime = 0)
    {
        try {
            if (!$formSubmitTime) {
                $formSubmitTime = time();
            }

            DB::beginTransaction();
            OpenShopCheckAcceptModel::query()
                                    ->where("orderNo", $params->orderNo)
                                    ->update(array_merge([
                                        "updatedAt"      => time(),
                                        "formSubmitTime" => $formSubmitTime,
                                        "updatedByUid"   => $rmsUser->id,
                                        "step"           => MainProcessEnum::SHOP_CHECK_BY_MANAGER,
                                    ], (array)$params));

            //TODO 主流程切换
            OpenShopMainProcessModel::query()->where("orderNo", $params->orderNo)
                                    ->update([
                                        "step"      => MainProcessEnum::MAIN_PROCESS_START_BUSINESS,
                                        "updatedAt" => time()
                                    ]);

            //TODO 转入开业流程
            //选址信息插入
            OpenShopStartBusinessModel::query()->insert([
                'orderNo'       => $params->orderNo,
                'mainProcessId' => OpenShopMainProcessModel::query()
                                                           ->where("orderNo", $params->orderNo)
                                                           ->first()->id,
                'createdAt'     => time()
            ]);

            // 初始化帮扶业务
            $shopId           = (int)OpenShopMainProcessModel::query()->where('orderNo', $params->orderNo)
                                                             ->value('shopId');
            $templateId       = CruiseTemplateService::getTemplateId(CruiseOrderModel::TYPE_NEW_SHOP_HELP);
            $cruiseOrderModel = (new CruiseOrderModel)->initShopHelper($params->orderNo, $shopId, $templateId);
            CruiseOrderProcessModel::initCruiseOrderProcess($cruiseOrderModel->id);
            (new CruiseOrderInputService($cruiseOrderModel))->initOrderInput($templateId);

            DB::commit();

            //TODO 任务
            event(new SignSiteMissionEvent(
                $params->orderNo,
                MissionTemplateEnum::STEP_STATUS_12,
                $rmsUser->id
            ));

            //todo 流程日志写入
            event(new OpenShopProcessEvent(
                $rmsUser->id,
                OpenShopMainProcessModel::query()->where("orderNo", $params->orderNo)->first()->id,
                MainProcessEnum::MAIN_PROCESS_SHOP_CHECK,
                MainProcessEnum::SHOP_CHECK_BY_MANAGER
            ));

            // 帮扶任务消息
            CruiseOrderInputService::helpSendFs($params->orderNo, CruiseOrderModel::STATUS_NOT_SUBMIT);

        } catch (Exception $exception) {
            Log::warning($exception);
            DB::rollBack();
            handleException($exception);
        }
    }

    /**
     * 验收详情
     *
     * @param string $orderNo
     * @return array|void
     * @throws Exception
     */
    public static function detail(string $orderNo)
    {
        try {

            $shopCheckAccept = OpenShopCheckAcceptModel::query()
                                                       ->where("orderNo", $orderNo)
                                                       ->get();

            return [
                "detail" => ShopCheckAcceptResource::collection($shopCheckAccept)
                                                   ->getIterator()
                                                   ->current()
            ];
        } catch (Exception $exception) {
            handleException($exception);
        }
    }


    /**
     * 验收问卷
     *
     * @param string $orderNo
     * @return array|void
     * @throws Exception
     */
    public static function formContent(string $orderNo)
    {
        try {
            $shopCheckAccept = OpenShopCheckAcceptModel::query()
                                                       ->where("orderNo", $orderNo)
                                                       ->first();

            if ($shopCheckAccept && $shopCheckAccept->step >= MainProcessEnum::SHOP_CHECK_BY_MANAGER) {
                $formContent = json_decode($shopCheckAccept->formContent, true);
            } else {
                $formContent = ConfigService::config("openShop", "checkAcceptFormContent")["checkAcceptFormContent"];
                if ($shopCheckAccept) {
                    $shopCheckAccept->formContent = json_encode($formContent, JSON_UNESCAPED_UNICODE);
                    $shopCheckAccept->save();
                }
            }

            return [
                "formContent" => $formContent
            ];
        } catch (Exception $exception) {
            handleException($exception);
        }
    }

    public static function formContentInput(array $formContent): array
    {
        foreach ($formContent as $k => &$part) {
//            $module = $part['module'];

            $content = $part['content'];

            foreach ($content as $val) {
                $subject = $val['subject'];

                $part['inputs'][] = AttributeSupport::getInstance('', 'text', $subject)
                                                    ->setValue('')
                                                    ->setValidateRules(ValidateSupport::getInstance(true))
                                                    ->setCustomAttribute([0, '是'], [1, '否'])
                                                    ->build();
            }

            unset($formContent[$k]['content']);
        }

        return $formContent;
    }


    /**
     * 经理确认 & 表单提交
     *
     * @param object $rmsUser
     * @param object $params
     * @throws Exception
     */
    public static function update(object $rmsUser, object $params)
    {
        try {
            DB::beginTransaction();

            $checkAccept  = OpenShopCheckAcceptModel::query()->where("orderNo", $params->orderNo)->first();
            $originalData = $checkAccept->getRawOriginal();
            $nowData      = array_merge([
                "updatedAt"      => time(),
                "formSubmitTime" => time(),
                "updatedByUid"   => $rmsUser->id,
            ], (array)$params);
            $checkAccept->setRawAttributes($nowData)->update();
            self::buildFormContent($originalData, $nowData);

            //todo 写入订单日志
            ChangeSupport::getInstance()->batchChangesWriteToOrderLog(
                OpenShopSignOrderModel::getOrderIdByOrderNo($params->orderNo),
                OpenShopSignOrderLogModel::UPDATE_SHOP_CHECK_ACCEPT,
                $rmsUser->username,
                $rmsUser->id
            );
            DB::commit();
        } catch (Exception $exception) {
            DB::rollBack();
            handleException($exception);
        }
    }

    private static function buildFormContent($before, $now)
    {
        if (!empty($before["formContent"]) && ($formContent = json_decode($before["formContent"], true)) !== false) {
            $beforeChanges = json_decode($before["formSubmit"], true);
            $nowChanges    = $now["formSubmit"];
            foreach ($formContent as $k => $content) {
                $changeDetail = [];
                foreach ($content["content"] as $qk => $question) {
                    array_push($changeDetail, [
                        "key"         => null,
                        "type"        => ChangeSupport::FILED_TYPE_STRING,
                        "beforeValue" => null,
                        "afterValue"  => null,
                        "beforeText"  => $beforeChanges ? $question["choose"][$beforeChanges[$k][$qk]["answer"]]["content"] : '',
                        "afterText"   => $question["choose"][$nowChanges[$k][$qk]["answer"]]["content"] ?? '',
                        "description" => $question["subject"]
                    ]);
                }
                ChangeSupport::getInstance()->pushChanges([
                    "theme"      => $content["module"],
                    "changeType" => ChangeSupport::CHANGE_TYPE_SINGLE_UPDATE,
                    "data"       => $changeDetail
                ]);
            }
        }
    }
}
